#pragma once
#include "base/function.h"
#include "util/noncopyable.h"
#include "base/config.h"
#include <netinet/in.h>

namespace net_tools
{
  class Eventloop;
  class Eventloopthread;
  class Logthread;
  namespace net
  {
    class Connect;
    class Socket;
  } // namespace net
  class Tcpclient : util::noncopyable
  {
  public:
    Tcpclient();
    ~Tcpclient(){};
    bool Startclient(bool loop,
                     std::string &ipaddr = _C::IP_ADDRESS,
                     int port = _C::DEFAULT_PORT,
                     int work_thread_number = _C::WORK_THREAD_POOL_SIZE,
                     int mempool_block_number = _C::BUFFER_MEMPOOL_BLOCK_NUMBER,
                     int mempool_block_size = _C::BUFFER_MEMPOOL_BLOCK_SIZE);
    bool Startclient(std::string &ipaddr,
                     int port,
                     Eventloop *eventloop_);
    void Set_before_loop_todo(eventloop_func cb) { before_loop_todo_ = std::move(cb); };
    void Set_connect_over_callback(connect_func cb) { connect_over_callback_ = std::move(cb); };

  private:
    void Set_thread_todo(eventloop_func cb) { thread_todo = std::move(cb); };
    static void Default_thread(Eventloop *eventloop, eventloop_func func);
    static void Default_message(net::Connect *connect);
    static void Default_close(net::Connect *connect);
    static void Default_user_close(net::Connect *connect);
    net::Socket *socket_;
    sockaddr_in sockaddr_;
    Eventloopthread *eventloopthread_;
    net_tools::Eventloop *eventloop_;
    eventloop_func before_loop_todo_;
    eventloop_func thread_todo;

    connect_func connect_over_callback_;
    connect_func message_callback_;
    connect_func close_callback_;
  };

} // namespace net_tools